package com.bk.bands;


import java.util.LinkedList;
import java.util.List;

import com.bk.bands.evaluate.Evaluable;
import com.bk.bands.evaluate.Evaluator;
import com.bk.bands.evaluate.ValueIterator;
import com.bk.bands.model.Band;
import com.bk.bands.model.CompositeField;
import com.bk.bands.model.Field;
import com.bk.bands.model.StackField;
import com.bk.bands.model.Template;
import com.bk.bands.print.Paper;
import com.bk.bands.runtime.BandsException;

/**
 * Created by IntelliJ IDEA.
 * User: sg0891787
 * Date: 3/5/12
 * Time: 9:45 AM
 */
public class Document
{
   private StackField documentField;

   public Document(StackField documentField)
   {
      this.documentField = documentField;
   }

   public static Document fill(Template template,DataSource source)
   {
      StackField documentFields = new StackField();

      List<Field> headerFields = template.getHeader();
      if(headerFields != null)
      {
         CompositeField footerField = evaluateFields(headerFields,source.getFooterValues());
         documentFields.pushField(footerField);
      }

      List<Band> bands = template.getBands();
      for(Band band : bands)
      {
         ValueIterator valueIterator = source.getBandValues(band.getName());
         documentFields.pushField(band.expand(valueIterator));
      }

      List<Field> footerFields = template.getFooter();
      if(footerFields != null)
      {
         CompositeField headerField = evaluateFields(footerFields,source.getFooterValues());
         documentFields.pushField(headerField);
      }

      return new Document(documentFields);
   }

   private static CompositeField evaluateFields(List<Field> fields,Evaluator evaluator)
   {
      List<Field> evaluatedFields = new LinkedList<Field>();
      for(Field field : fields)
      {
         if(field instanceof Evaluable)
         {
            evaluatedFields.add((((Evaluable) field).evaluate(evaluator)));
         }
         else
         {
            evaluatedFields.add(field);
         }
      }
      return new CompositeField(evaluatedFields);
   }

   public void print(Paper paper) throws BandsException
   {
      documentField.print(paper);
   }

   public int getWidth()
   {
      return documentField.getSize().width;
   }

   public int getHeight()
   {
      return documentField.getSize().height;
   }

}
